package main

import "fmt"

// 我们可能会说这和 switch case 也没有差别，并且编写这些类型及其扩展函数会额外的代码和工作量，
// 幸运的是这些通用类型均有社区支持 https://github.com/samber/mo
// https://github.com/samber/lo ：基于 Go 1.18+ 泛型的 Lodash 风格的 Go 库
// https://github.com/samber/do ：基于 Go 1.18+ 泛型的依赖注入工具包

type Either[T1 any, T2 any] struct {
	argId int8
	arg1  T1
	arg2  T2
}

func (e Either[T1, T2]) ForEach(arg1Cb func(T1), arg2Cb func(T2)) {
	switch e.argId {
	case 1:
		arg1Cb(e.arg1)
	case 2:
		arg2Cb(e.arg2)
	}
}

type PolicyForceStay struct {
	name string
}

type PolicySplash struct {
	name string
}

type Policy struct {
	Name    string
	Type    int8
	Setting Either[PolicyForceStay, PolicySplash]
}

func main() {
	policy := Policy{"jwj", 1,
		Either[PolicyForceStay, PolicySplash]{
			1, PolicyForceStay{"PolicyForceStay"}, PolicySplash{"PolicySplash"},
		},
	}
	policy.Setting.ForEach(func(stay PolicyForceStay) {
		fmt.Println(stay)
	}, func(splash PolicySplash) {
		fmt.Println(splash)
	})
}
